// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.

namespace Microsoft.Samples.Commerce.Order.CommerceEntities
{
    using Microsoft.Commerce.Contracts;

    /// <summary>
    /// Represents a product variant.
    /// </summary>
    public class Variant : CatalogEntity
    {
        #region Constructors

        /// <summary>
        /// defines the model name for this commerce entity
        /// </summary>
        public new const string ModelNameDefinition = "Variant";

        /// <summary>
        /// Initializes a new instance of the <see cref="Variant"/> class.
        /// </summary>
        public Variant()
            : base()
        {
            this.CommerceEntity = new CommerceEntity(Variant.ModelNameDefinition);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Variant"/> class.
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        public Variant(CommerceEntity commerceEntity)
            : base(commerceEntity)
        {
            this.CommerceEntity = commerceEntity;
        }

        #endregion

        /// <summary>
        /// Gets or sets the product id.
        /// </summary>
        /// <value>the id of the product</value>
        public string ProductId
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(PropertyName.ProductId) as string;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(PropertyName.ProductId, value);
            }
        }

        /// <summary>
        /// Gets or sets the inventory items.
        /// </summary>
        /// <value>a list of Relationships where the target is of type InventoryItem.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList InventoryItems
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.InventoryItems) as CommerceRelationshipList;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.InventoryItems, value);
            }
        }

        /// <summary>
        /// Gets or sets the inventory condition.
        /// </summary>
        /// <value>The inventory condition.</value>
        public int? InventoryCondition
        {
            get
            {
                return (int?)this.CommerceEntity.GetPropertyValue(PropertyName.InventoryCondition);
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(PropertyName.InventoryCondition, value ?? null);
            }
        }

        #region Implicit operators
        /// <summary>
        /// Implicit operator to convert to a variant
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "Design decision for API")]
        public static implicit operator Variant(CommerceEntity commerceEntity)
        {
            System.Diagnostics.Debug.Assert(Variant.ModelNameDefinition.Equals(commerceEntity.ModelName), "Unexpected model name");
            return new Variant(commerceEntity);
        }
        #endregion

        /// <summary>
        /// Names of the properties exposed by this commerce entity.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public new class PropertyName : CatalogEntity.PropertyName
        {
            /// <summary>
            /// The inventory condition for the variant.
            /// </summary>
            public const string InventoryCondition = "InventoryCondition";

            /// <summary>
            /// The Product Id for the variant.
            /// </summary>
            public const string ProductId = "ProductId";
        }

        /// <summary>
        /// Class defining Properties of Items that may be related to a Product.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Justification = "Required because of API specification (i.e. DataContract design)")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public class RelationshipName
        {
            /// <summary>
            /// The name of the InventoryItems relationship.
            /// </summary>
            public const string InventoryItems = "InventoryItems";
        }
    }
}
